import call from './call.js'

const is = (tokens) => {
  return tokens.peek().type === 'keyword' && tokens.peek().value === 'while'
}

const parse = (tokens) => {
  const node = {
    type: 'WhileStatement',
    test: {
      type: null,
      left: null,
      operator: null,
      right: null
    },
    consequent: {
      type: null,
      body: []
    }
  }

  tokens.next()

  if (tokens.peek().type !== 'punctuation' || tokens.peek().value !== '(') {
    tokens.croak(`Can't handle token: ${ tokens.peek().value }`)
  }

  tokens.next()

  if (tokens.peek().type === 'identifier') {
    node.test.left = {
      type: 'Identifier',
      name: tokens.peek().value
    }
  } else if (tokens.peek().type === 'number' || tokens.peek().type === 'literal') {
    node.test.left = {
      type: 'Literal',
      value: tokens.peek().value
    }
  } else {
    tokens.croak(`Can't handle token: ${ tokens.peek().value }`)
  }

  tokens.next()

  if (tokens.peek().type === 'operator' && /^(>|<|>=|<=|==|!=)$/.test(tokens.peek().value)) {
    node.test.type = 'BinaryExpression'
    node.test.operator = tokens.peek().value
  } else {
    tokens.croak(`Can't handle token: ${ tokens.peek().value }`)
  }

  tokens.next()

  if (tokens.peek().type === 'identifier') {
    node.test.right = {
      type: 'Identifier',
      name: tokens.peek().value
    }
  } else if (tokens.peek().type === 'number' || tokens.peek().type === 'literal') {
    node.test.right = {
      type: 'Literal',
      value: tokens.peek().value
    }
  } else {
    tokens.croak(`Can't handle token: ${ tokens.peek().value }`)
  }

  tokens.next()

  if (tokens.peek().type !== 'punctuation' || tokens.peek().value !== ')') {
    tokens.croak(`Can't handle token: ${ tokens.peek().value }`)
  }

  tokens.next()

  if (tokens.peek().type !== 'operator' || tokens.peek().value !== '->') {
    tokens.croak(`Can't handle token: ${ tokens.peek().value }`)
  }

  tokens.next()

  if (tokens.peek().type === 'punctuation' && tokens.peek().value === '{') {
    tokens.next()

    node.consequent.type = 'BlockStatement'
    node.consequent.body = []

    let count = 0
    while (!(tokens.peek().type === 'punctuation' && tokens.peek().value === '}') || count > 0) {
      if (tokens.peek().type === 'punctuation' && tokens.peek().value === '{') {
        count++
      } else if (tokens.peek().type === 'punctuation' && tokens.peek().value === '}') {
        count--
      }
      node.consequent.body.push(tokens.next())
    }

    tokens.next()
  } else if (tokens.peek().type === 'identifier') {
    node.consequent.type = 'ExpressionStatement'
    node.consequent.body = call.parse(tokens)
  } else {
    tokens.croak(`Can't handle token: ${ tokens.peek().value }`)
  }

  return node
}

export default {
  is,
  parse
}